package com.keqiang.chart.impl.axis.impl.bar

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.text.Layout
import android.text.TextPaint
import androidx.annotation.ColorInt
import com.keqiang.chart.utils.ObjectPool
import com.keqiang.chart.utils.px
import com.keqiang.utils.PaintUtils
import com.keqiang.utils.PaintUtils.getChartHeight

/**
 * 柱状图默认点击高亮
 *
 * @author Created by wanggaowan on 2022/7/29 08:55
 */
open class BarChartHighLightRender @JvmOverloads constructor(
    chart: BarChart,
    /**
     * 覆盖在柱状图上遮罩的颜色
     */
    @ColorInt val maskColor: Int = 0x55000000) : HighLightRender(chart) {

    override fun onDraw(canvas: Canvas, start: Float, top: Float, end: Float, bottom: Float, data: List<BarEntity>) {
        val paint = ObjectPool.obtainPaint<Paint>()
        paint.color = maskColor
        paint.style = Paint.Style.FILL
        data.forEach {
            canvas.drawRect(it.drawRectF, paint)
            getText(it)?.let { text ->
                drawValueText(canvas, it, start, end, top, text)
            }
        }
        ObjectPool.recyclePaint(paint)
    }

    /**
     * 绘制柱状图文本
     */
    protected open fun drawValueText(canvas: Canvas, data: BarEntity, start: Float, end: Float, top: Float, text: CharSequence) {
        val textPaint = ObjectPool.obtainPaint<TextPaint>(true)
        if (text.isNotEmpty()) {
            textPaint.color = getTextColor(data)
            textPaint.textSize = getTextSize(data)

            // 测量指定文本每行的最大宽度
            val split = text.split("\n")
            var maxOneLineWidth = 0f
            split.forEach { str ->
                maxOneLineWidth = textPaint.measureText(str).coerceAtLeast(maxOneLineWidth)
            }

            var maxWidth = (end - start).toInt()
            val textLine = PaintUtils.getTextLine(text, textPaint, maxWidth)
            val chartHeight = textPaint.getChartHeight()
            var align = Layout.Alignment.ALIGN_CENTER
            val drawX = if (maxOneLineWidth > maxWidth) {
                align = Layout.Alignment.ALIGN_NORMAL
                start
            } else {
                maxWidth = maxOneLineWidth.toInt()
                val cx = data.drawRectF.centerX()
                if (cx - start >= maxOneLineWidth / 2f) {
                    if (cx + maxOneLineWidth / 2f > end) {
                        align = Layout.Alignment.ALIGN_OPPOSITE
                        end - maxOneLineWidth
                    } else {
                        cx - maxOneLineWidth / 2f
                    }
                } else if (cx + maxOneLineWidth / 2f > end) {
                    align = Layout.Alignment.ALIGN_OPPOSITE
                    end - maxOneLineWidth
                } else {
                    align = Layout.Alignment.ALIGN_NORMAL
                    start
                }
            }

            val drawY = (data.drawRectF.top - chartHeight * textLine).coerceAtLeast(top)

            canvas.save()
            canvas.translate(drawX, drawY)
            PaintUtils.drawText(canvas, textPaint, text, maxWidth, Int.MAX_VALUE, align)
            canvas.restore()
        }

        ObjectPool.recyclePaint(textPaint)
    }

    /**
     * 获取需要绘制的文本
     */
    open fun getText(lineEntity: BarEntity): CharSequence? = null

    /**
     * 获取需要绘制的字体大小
     */
    open fun getTextSize(lineEntity: BarEntity): Float = 16f.px

    /**
     * 获取需要绘制的字体颜色
     */
    open fun getTextColor(lineEntity: BarEntity): Int = Color.BLACK
}